<!-- components/FloatingBall.vue -->
<template>
  <div
      class="fixed z-50 rounded-full shadow-lg cursor-move transition-all duration-300"
      :style="{
      width: size + 'px',
      height: size + 'px',
      backgroundColor: color,
      bottom: bottom + 'px',
      right: right + 'px',
      transform: isDragging ? 'scale(1.05)' : 'scale(1)',
      boxShadow: isDragging
        ? '0 0 20px rgba(0, 0, 0, 0.3)'
        : '0 5px 15px rgba(0, 0, 0, 0.2)',
    }"
      @mousedown="startDrag"
      @touchstart="startDrag"
      @mouseup="endDrag"
      @touchend="endDrag"
      @mousemove="handleDrag"
      @touchmove="handleDrag"
      @click="handleClick"
  >
    <slot>
      <div class="w-full h-full flex items-center justify-center">
        <span class="text-white font-bold">+</span>
      </div>
    </slot>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
// 显式导入 defineProps 和 defineEmits
import { defineProps, defineEmits } from 'vue';

const props = defineProps({
  // 悬浮球的大小
  size: {
    type: Number,
    default: 60,
  },
  // 悬浮球的背景颜色
  color: {
    type: String,
    default: '#007BFF',
  },
  // 悬浮球初始位置
  initialPosition: {
    type: Object,
    default: () => ({
      bottom: 30,
      right: 30,
    }),
  },
});

// 定义 emits 选项
const emit = defineEmits(['click']);

// 悬浮球位置状态
const bottom = ref(props.initialPosition.bottom);
const right = ref(props.initialPosition.right);
const isDragging = ref(false);
const startX = ref(0);
const startY = ref(0);
const initialBottom = ref(0);
const initialRight = ref(0);
const windowWidth = ref(window.innerWidth);
const windowHeight = ref(window.innerHeight);

// 处理窗口大小变化
const handleResize = () => {
  windowWidth.value = window.innerWidth;
  windowHeight.value = window.innerHeight;
};

// 开始拖拽
const startDrag = (e) => {
  // 阻止事件冒泡
  e.stopPropagation();
  // 区分鼠标和触摸事件
  const event = e.type.includes('mouse') ? e : e.touches[0];
  isDragging.value = true;
  startX.value = event.clientX;
  startY.value = event.clientY;
  initialBottom.value = bottom.value;
  initialRight.value = right.value;
};

// 处理拖拽
const handleDrag = (e) => {
  if (!isDragging.value) return;
  e.preventDefault();
  const event = e.type.includes('mouse') ? e : e.touches[0];

  // 计算位移
  const dx = event.clientX - startX.value;
  const dy = event.clientY - startY.value;

  // 更新位置（相对于右下角）
  right.value = Math.max(
      0,
      Math.min(windowWidth.value - props.size, initialRight.value - dx)
  );
  bottom.value = Math.max(
      0,
      Math.min(windowHeight.value - props.size, initialBottom.value + dy)
  );
};

// 结束拖拽
const endDrag = () => {
  isDragging.value = false;
  // 吸附到边缘效果
  if (right.value < windowWidth.value / 2) {
    // 吸附到左侧
    right.value = windowWidth.value - props.size;
  }
};

// 点击事件
const handleClick = (e) => {
  if (!isDragging.value) {
    // 只有在不是拖拽操作时才触发点击事件
    emit('click');
  }
};

// 生命周期钩子
onMounted(() => {
  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});

// 监听props变化
watch(
    () => props.initialPosition,
    (newPosition) => {
      bottom.value = newPosition.bottom;
      right.value = newPosition.right;
    },
    { deep: true }
);
</script>

<style scoped>
/* 添加动画效果 */
div {
  transition: all 0.3s ease;
  user-select: none;
  -webkit-user-select: none;
}
</style>